import { Injectable, Logger } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, DataSource } from 'typeorm';
import { MasterCategory } from '../entities/master-category.entity';
import { SiteCategoryMap } from '../entities/site-category-map.entity';
import { MASTER_CATEGORIES_SEED } from '../data/master-categories';
import { SITE_CATEGORY_MAPPINGS_SEED } from '../data/site-mappings';

@Injectable()
export class CategoryMappingService {
  private readonly logger = new Logger(CategoryMappingService.name);

  constructor(
    @InjectRepository(MasterCategory)
    private readonly masterCategoryRepository: Repository<MasterCategory>,
    @InjectRepository(SiteCategoryMap)
    private readonly siteCategoryMapRepository: Repository<SiteCategoryMap>,
    private readonly dataSource: DataSource,
  ) {}

  /**
   * 映射站点分类到母分类
   * @param site 站点名称
   * @param siteCategory 站点分类名称
   * @returns 映射后的母分类，未找到则返回默认分类
   */
  async mapSiteCategoryToMaster(
    site: string,
    siteCategory: string,
  ): Promise<MasterCategory> {
    try {
      // 查找站点映射
      const mapping = await this.siteCategoryMapRepository.findOne({
        where: {
          site,
          siteCategory,
          status: 1, // 只查找启用的映射
        },
        relations: ['masterCategory'],
      });

      if (mapping && mapping.masterCategory) {
        return mapping.masterCategory;
      }

      // 如果没有找到映射，返回默认分类（都市）
      const defaultCategory = await this.masterCategoryRepository.findOne({
        where: { id: 5, status: 1 }, // 5 = 都市分类
      });

      if (!defaultCategory) {
        throw new Error('默认母分类未找到');
      }

      this.logger.warn(
        `未找到站点分类映射: ${site}-${siteCategory}，使用默认分类: ${defaultCategory.name}`,
      );

      return defaultCategory;
    } catch (error) {
      this.logger.error(`映射分类失败: ${site}-${siteCategory}`, error);
      throw error;
    }
  }

  /**
   * 批量映射站点分类到母分类
   * @param categories 分类数组，格式为 [{ site, category }]
   * @returns 映射结果数组
   */
  async batchMapSiteCategories(
    categories: Array<{ site: string; category: string }>,
  ): Promise<Array<{ site: string; category: string; masterCategory: MasterCategory }>> {
    const results: Array<{ site: string; category: string; masterCategory: MasterCategory }> = [];

    for (const item of categories) {
      try {
        const masterCategory = await this.mapSiteCategoryToMaster(
          item.site,
          item.category,
        );
        results.push({
          site: item.site,
          category: item.category,
          masterCategory,
        });
      } catch (error) {
        this.logger.error(`批量映射失败: ${item.site}-${item.category}`, error);
        // 继续处理其他分类
      }
    }

    return results;
  }

  /**
   * 获取所有母分类
   */
  async getAllMasterCategories(): Promise<MasterCategory[]> {
    return await this.masterCategoryRepository.find({
      where: { status: 1 },
      order: { sortOrder: 'ASC', id: 'ASC' },
    });
  }

  /**
   * 获取指定站点的所有映射
   */
  async getSiteMappings(site: string): Promise<SiteCategoryMap[]> {
    return await this.siteCategoryMapRepository.find({
      where: { site, status: 1 },
      relations: ['masterCategory'],
      order: { siteCategory: 'ASC' },
    });
  }

  /**
   * 添加新的站点映射
   */
  async addSiteMapping(
    site: string,
    siteCategory: string,
    masterId: number,
    description?: string,
  ): Promise<SiteCategoryMap> {
    // 检查是否已存在
    const existing = await this.siteCategoryMapRepository.findOne({
      where: { site, siteCategory },
    });

    if (existing) {
      // 更新现有映射
      existing.masterId = masterId;
      existing.description = description;
      existing.status = 1;
      return await this.siteCategoryMapRepository.save(existing);
    }

    // 创建新映射
    const mapping = this.siteCategoryMapRepository.create({
      site,
      siteCategory,
      masterId,
      description,
      status: 1,
    });

    return await this.siteCategoryMapRepository.save(mapping);
  }

  /**
   * 初始化母分类数据
   */
  async initializeMasterCategories(): Promise<void> {
    this.logger.log('开始初始化母分类数据');

    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      // 检查是否已初始化
      const existingCount = await queryRunner.manager.count(MasterCategory);
      if (existingCount > 0) {
        this.logger.log('母分类数据已存在，跳过初始化');
        await queryRunner.rollbackTransaction();
        return;
      }

      // 批量插入母分类数据
      for (const categoryData of MASTER_CATEGORIES_SEED) {
        const category = queryRunner.manager.create(MasterCategory, {
          ...categoryData,
          status: 1,
        });
        await queryRunner.manager.save(category);
      }

      await queryRunner.commitTransaction();
      this.logger.log(`母分类数据初始化完成，共${MASTER_CATEGORIES_SEED.length}条记录`);
    } catch (error) {
      await queryRunner.rollbackTransaction();
      this.logger.error('母分类数据初始化失败', error);
      throw error;
    } finally {
      await queryRunner.release();
    }
  }

  /**
   * 初始化站点映射数据
   */
  async initializeSiteMappings(): Promise<void> {
    this.logger.log('开始初始化站点映射数据');

    const queryRunner = this.dataSource.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();

    try {
      // 检查是否已初始化
      const existingCount = await queryRunner.manager.count(SiteCategoryMap);
      if (existingCount > 0) {
        this.logger.log('站点映射数据已存在，跳过初始化');
        await queryRunner.rollbackTransaction();
        return;
      }

      // 批量插入站点映射数据
      for (const mappingData of SITE_CATEGORY_MAPPINGS_SEED) {
        const mapping = queryRunner.manager.create(SiteCategoryMap, {
          ...mappingData,
          status: 1,
        });
        await queryRunner.manager.save(mapping);
      }

      await queryRunner.commitTransaction();
      this.logger.log(`站点映射数据初始化完成，共${SITE_CATEGORY_MAPPINGS_SEED.length}条记录`);
    } catch (error) {
      await queryRunner.rollbackTransaction();
      this.logger.error('站点映射数据初始化失败', error);
      throw error;
    } finally {
      await queryRunner.release();
    }
  }

  /**
   * 初始化所有映射数据
   */
  async initializeAll(): Promise<void> {
    await this.initializeMasterCategories();
    await this.initializeSiteMappings();
  }
}